using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SIOGDE.AccesoDatos.Entidades;
using SIOGDE.AccesoDatos.Contratos;
using SIOGDE.Negocios.Servicios;
using SIOGDE.Negocios.Excepciones;
using System.ServiceModel.Activation;
using Didsoft.Core.Exceptions;
using SIOGDE.Negocios.Servicios.Wcf;
using SIOGDE.AccesoDatos.Entidades.Lites;

namespace SIOGDE.Negocios
{
   /// <summary>
   /// Implementacion de la interface IUnidadMilitarNegociosServicio, los metodos que estan definidos en el contrato IUnidadMilitarNegociosServicio serán accesibles desde un contexto externo
   /// </summary>	
    [WcfErrorBehavior]
    [WcfSilverlightFaultBehavior]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
   public class UnidadMilitarNegocios : IUnidadMilitarNegociosServicio, IUnidadMilitarWcfServicio
   {
	private IUnidadMilitarAccesoDatos accesoDatos;
	public UnidadMilitarNegocios()
	{		
		accesoDatos = DataFactory.Current.GetUnidadMilitarAccesoDatos();
	}
	
	/// <summary>
    /// Devuelve una lista de UnidadMilitar's de las ocurrencias encontradas a partir del filtro
    /// </summary>    
	public List<UnidadMilitar> BuscarPorFiltro(string filtro)
	{
		return accesoDatos.BuscarPorFiltro(filtro).ToList();
	}

	#region operaciones básicas
	
	/// <summary>
    /// Elimina la entidad UnidadMilitar, lanzará una excepcion si la entidad guarda dependencia a otras entidades
    /// </summary>	
	public void Eliminar(UnidadMilitar entidad)
	{
		try
		{
		    accesoDatos.Delete(accesoDatos.GetById(entidad.Id));
	    }
		catch(Exception ex)
		{
		   throw new UnidadMilitarEliminarExcepcion("UnidadMilitar");
		}
	}
	
	/// <summary>
    /// Devuelve UnidadMilitar, buscada por su Id, si no existe, entonces devuelve null
    /// </summary>	
	public UnidadMilitar ObtenerPorId(object Id)
	{
		return accesoDatos.GetById(Id);
	}

	/// <summary>
    /// Devuelve List<UnidadMilitar>, de todas la entidades de ese tipo
    /// </summary>	
	public List<UnidadMilitar> ObtenerTodas()
	{
		return accesoDatos.GetAll().ToList();
	}

	
	/// <summary>
    /// Guarda UnidadMilitar, previa ejecucion satisfactoria de las reglas de negocio
    /// </summary>	
	public UnidadMilitar Guardar(UnidadMilitar entidad)
	{
		//Agregar aqui las reglas de negocio.......	
		if(entidad==null)
		 throw new UnidadMilitarRequeridoExcepcion(); 
		
		#region Foreign Keys Values
                if(entidad.CategoriaUnidadId_FK > 0 && entidad.CategoriaUnidad==null)
                    entidad.CategoriaUnidad = DataFactory.Current.GetCategoriaUnidadAccesoDatos().GetById(entidad.CategoriaUnidadId_FK);
                if(entidad.FuerzaId_FK > 0 && entidad.Fuerza==null)
                    entidad.Fuerza = DataFactory.Current.GetFuerzaAccesoDatos().GetById(entidad.FuerzaId_FK);
                if(entidad.TipoUnidadId_FK > 0 && entidad.TipoUnidad==null)
                    entidad.TipoUnidad = DataFactory.Current.GetTipoUnidadAccesoDatos().GetById(entidad.TipoUnidadId_FK);
                if(entidad.UnidadPadreId_FK > 0 && entidad.UnidadPadre==null)
                    entidad.UnidadPadre = DataFactory.Current.GetUnidadMilitarAccesoDatos().GetById(entidad.UnidadPadreId_FK);
                if (entidad.RegionId_FK > 0 && entidad.Region == null)
                    entidad.Region =   Didsoft.DUA.AccesoDatos.Contratos.DataFactory.Current.GetDUA_RegionAccesoDatos().GetById(entidad.RegionId_FK);
                #endregion

                if (string.IsNullOrEmpty(entidad.Guid))
                    entidad.Guid = System.Guid.NewGuid().ToString();

		if (entidad.Id == 0)
			accesoDatos.Insert(entidad);
		else
			accesoDatos.Update(entidad);

		return entidad;
	}

	#endregion

       #region opciones de destino

    public List<UnidadAsignadaInfo> GetOpcionesDeDestino()
    { 
        Persona personaSession = SIOGDE.Negocios.Global.Session.UserInfo.Persona;        
        Gestion gestion = SIOGDE.Negocios.Global.Session.GestionActiva;

        DestinoAsignado destino = DataFactory.Current.GetDestinoAsignadoAccesoDatos().GetPorPersonaId(personaSession.Id , gestion.Id);
        if (destino != null)
            throw new DestinoNoPuedeSerDuplicadoExcepcion();
        
       //obtener destinos anteriores
       IList<DestinoAsignado> destinos = DataFactory.Current.GetDestinoAsignadoAccesoDatos().GetPorPersonaId(personaSession.Id);

        PersonaArma personaArma = DataFactory.Current.GetPersonaArmaAccesoDatos().GetPorPersonaId(personaSession.Id);


       //verificar si los anteriores a su antiguedad ya tienen destino / esto debe controlar por arma y ascenso
        //IList<Persona> antiguosNoDestinados = DataFactory.Current.GetPersonaAccesoDatos().GetAntiguosNoDestinados(personaSession.NumAntiguedadEgreso.Value, gestion.Id, personaSession.FechaEgreso.Value, personaArma.Arma.Id);

        var ascendido = DataFactory.Current.GetHistorialAscensoAccesoDatos().GetPorPersonaId(personaSession.Id).OrderByDescending(p => p.FechaAscenso).FirstOrDefault();
        if (ascendido == null)
            throw new Exception("La persona no tiene ascenso registrado, comunique al administrador del sistema");

        IList<Persona> antiguosNoDestinados = DataFactory.Current.GetPersonaAccesoDatos().GetAntiguosNoDestinados(ascendido.NumAntiguedadArma, 
                                                                                                                  gestion.Id,
                                                                                                                  personaSession.FechaEgreso.Value, 
                                                                                                                  personaArma.Arma.Id, 
                                                                                                                  SIOGDE.Negocios.Global.Session.UserInfo.Rol.Id);

        if (antiguosNoDestinados.Count > 0)
            throw new Exception("Personal mas antiguo de su promocion o año de egreso aún no confirmó su destino, vuelva a intentar hasta que el sistema lo valide.");

        //obtener los destinos a los cuales est]a habilitada la persona / no esta discriminando por especialidad
        List<UnidadAsignadaInfo> posiblesDestinos = DataFactory.Current.GetUnidadMilitarAccesoDatos().GetDestinosSugerentes(personaSession.Id, gestion.Id).ToList();


        //obtener nota de ascenso al grado
       int antiguedad = personaSession.NumAntiguedadEgreso.Value;

        //obtener nota de foja de concepto de los tres ultimos anios
       return posiblesDestinos;
    
    }

       #endregion



    public UnidadMilitar GetPorGuid(string guid)
    {
        return DataFactory.Current.GetUnidadMilitarAccesoDatos().GetPorGuid(guid);
    }

    public List<UnidadMilitar> ObtenerUnidadesRaiz()
    {
        return accesoDatos.GetUnidadesRaiz().ToList();
    }


    public List<UnidadMilitar> ObtenerDependientes(int unidadId)
    {
        return accesoDatos.GetDependientesDeUnidad(unidadId).ToList();
    }
   }
}


